package com.hh.generator.core.generator;

import com.hh.generator.common.dto.ColumnEntity;
import com.hh.generator.common.dto.TableEntity;
import com.hh.generator.core.model.ClassModel;
import com.hh.generator.core.model.Config;
import com.hh.generator.core.model.FieldModel;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.hh.generator.common.util.TableToClassConvertUtil.fieldName;

public abstract class AbstractTableBaseGenerator extends AbstractGenerator {

    protected Config config;
    protected TableEntity tableEntity;
    protected List<ColumnEntity> columnEntityList;

    protected static String PACKAGE_DATE = "java.util.Date";
    protected static String PACKAGE_BIG_DECIMAL = "java.math.BigDecimal";

    public AbstractTableBaseGenerator(Config config, TableEntity tableEntity, List<ColumnEntity> columnEntityList) {
        this.config = config;
        this.tableEntity = tableEntity;
        this.columnEntityList = columnEntityList;
    }

    public abstract String fileName();

    public String generate() {
        ClassModel classModel = buildModel();
        String fileContent = doGenerate(classModel, getTemplateName());
        return fileContent;
    }

    public Map<String, String> generateEnums() {
        Map<String, String> map = new HashMap<>();
        for (ColumnEntity columnEntity : columnEntityList) {
            if (StringUtils.isNotBlank(columnEntity.getColumnComment()) && columnEntity.getColumnComment().startsWith("枚举")) {
                ClassModel classModel = buildEnumModel(columnEntity);
                String fileContent = doGenerate(classModel, getTemplateName());
                map.put(enumFileName(columnEntity), fileContent);
            }
        }
        return map;
    }


    protected ClassModel buildEnumModel(ColumnEntity columnEntity) {
        return null;
    }

    protected String enumFileName(ColumnEntity columnEntity) {
        return null;
    }

    protected abstract ClassModel buildModel();

    protected List<FieldModel> buildFieldModels() {
        List<FieldModel> fieldModels = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(columnEntityList)) {
            for (ColumnEntity columnEntity : columnEntityList) {
                String fieldName = fieldName(columnEntity.getColumnName());
                FieldModel fieldModel = new FieldModel();
                fieldModel.setFieldName(fieldName);
                fieldModel.setFieldComment(columnEntity.getColumnComment());
                fieldModel.setFieldType(config.getDbColumnTypeMap().get(columnEntity.getDataType()));
                fieldModel.setUpperColumnName(columnEntity.getColumnName().toUpperCase());
                fieldModel.setLowerColumnName(columnEntity.getColumnName().toLowerCase());
                fieldModel.setGetMethod("get" + org.apache.commons.lang.StringUtils.capitalize(fieldName));
                fieldModel.setSetMethod("set" + org.apache.commons.lang.StringUtils.capitalize(fieldName));
                fieldModels.add(fieldModel);
            }
        }
        return fieldModels;
    }

    protected List<String> buildImports(List<FieldModel> fieldModels) {
        List<String> imports = new ArrayList<>();
        for (FieldModel fieldModel : fieldModels) {
            switch (fieldModel.getFieldType()) {
                case "Date":
                    imports.add(PACKAGE_DATE);
                    break;
                case "BigDecimal":
                    imports.add(PACKAGE_BIG_DECIMAL);
                    break;
                default:
                    break;
            }
        }
        return imports.stream().distinct().collect(Collectors.toList());
    }

    protected abstract String getTemplateName();
}
